package com.usefullc.extinguisher.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.usefullc.common.exception.BizException;
import com.usefullc.common.util.BeanUtils;
import com.usefullc.extinguisher.domain.CheckStandard;
import com.usefullc.extinguisher.mapper.CheckStandardMapper;
import com.usefullc.extinguisher.query.CheckStandardQuery;
import com.usefullc.extinguisher.vo.CheckStandardVo;
import com.usefullc.system.entity.Pager;
import com.usefullc.system.service.AbstractBizService;
import com.usefullc.system.service.SerialNumberService;
import com.usefullc.system.vo.TreeVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 检查标准服务类
 * @author: 星空
 * @date: 2022-11-19
 */
@Service
public class CheckStandardService extends AbstractBizService<CheckStandardMapper, CheckStandard, CheckStandardQuery> {

    @Autowired
    private SerialNumberService serialNumberService;

    @Override
    protected QueryWrapper<CheckStandard> getQueryWrapper(CheckStandardQuery query) {
        QueryWrapper<CheckStandard> queryWrapper = super.getQueryWrapper(query);
        return queryWrapper;
    }

    public List<CheckStandard> getChildrenByCodeLike(String codeLike) {
        CheckStandardQuery query = new CheckStandardQuery();
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        query.setCodeLike(codeLike);
        return this.findAll(query);
    }

    public List<CheckStandard> getChildrenByParentId(Long parentId) {
        CheckStandardQuery query = new CheckStandardQuery();
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        query.setParentId(parentId);
        return this.findAll(query);
    }


    public Pager<CheckStandardVo> findVoByPage(CheckStandardQuery query) {
        query.setParentId(0L);
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        Pager<CheckStandard> pager = this.findByPage(query);
        List<CheckStandard> dataList = pager.getDataList();
        Pager<CheckStandardVo> newPager = new Pager<>(pager);
        List<CheckStandardVo> newDataList = new ArrayList<>();
        newPager.setDataList(newDataList);
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (CheckStandard checkStandard : dataList) {
//                checkStandardVo.setChildren(Lists.newArrayList());
                CheckStandardVo checkStandardVo = BeanUtils.beanCopy(checkStandard, CheckStandardVo.class);
                newDataList.add(checkStandardVo);

                //

                List<CheckStandardVo> children = new ArrayList<>();
                //获取子集
                List<CheckStandard> childDataList = getChildrenByCodeLike(checkStandard.getCode());

                setChildren(childDataList,children,checkStandardVo);

            }
        }
        return newPager;
    }

    private void setChildren(List<CheckStandard> childDataList, List<CheckStandardVo> children, CheckStandardVo checkStandardVo){
        for (CheckStandard checkStandard : childDataList) {
            if (checkStandard.getParentId() != checkStandardVo.getId().longValue()) {
                continue;
            }
            CheckStandardVo childCheckStandardVo = BeanUtils.beanCopy(checkStandard, CheckStandardVo.class);
            children.add(childCheckStandardVo);
            List<CheckStandardVo> subChildren = new ArrayList<>();
            setChildren(childDataList,subChildren,childCheckStandardVo);
        }
        if(children.size() > 0){
            checkStandardVo.setChildren(children);
        }
    }

    public List<TreeVo> listTree(CheckStandardQuery query){
        query.setParentId(0L);
        List<CheckStandard> dataList = this.findAll(query);
        List<TreeVo> newDataList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (CheckStandard checkStandard : dataList) {
                TreeVo treeVo = new TreeVo();
                newDataList.add(treeVo);
                treeVo.setTitle(checkStandard.getName());
                treeVo.setText(checkStandard.getName());
                treeVo.setValue(checkStandard.getId().toString());
                treeVo.setKey(checkStandard.getId().toString());
                treeVo.setId(checkStandard.getId());
                List<TreeVo> children = new ArrayList<>();
                //获取子集
                List<CheckStandard> childDataList = getChildrenByCodeLike(checkStandard.getCode());

                setTreeChildren(childDataList,children,treeVo);
            }
        }
        //添加根目录
//        TreeVo treeVo = new TreeVo();
//        treeVo.setTitle("根目录");
//        treeVo.setValue("0");
//        treeVo.setKey("0");
//        newDataList.add(0,treeVo);
        return newDataList;
    }

    private void setTreeChildren(List<CheckStandard> childDataList, List<TreeVo> children, TreeVo treeVo){
        for (CheckStandard childCheckStandard : childDataList) {
            if (childCheckStandard.getParentId() != Long.valueOf(treeVo.getValue()).longValue()) {
                continue;
            }
            TreeVo childTreeVo = new TreeVo();
            childTreeVo.setTitle(childCheckStandard.getName());
            childTreeVo.setText(childCheckStandard.getName());
            childTreeVo.setValue(childCheckStandard.getId().toString());
            childTreeVo.setKey(childCheckStandard.getId().toString());
            childTreeVo.setId(childCheckStandard.getId());
            children.add(childTreeVo);

            List<TreeVo> subChildren = new ArrayList<>();
            setTreeChildren(childDataList,subChildren,childTreeVo);
        }
        if(children.size() > 0){
            treeVo.setChildren(children);
        }
    }


    @Override
    public boolean save(CheckStandard entity) {
        super.save(entity);
        return this.update(entity);
    }

    @Override
    public boolean update(CheckStandard entity) {
        //设置路径
//        entity.setUrl("/cmsEnglish/checkStandard/"+entity.getId()+".html");
        return super.update(entity);
    }

    public CheckStandard saveCheckStandard(CheckStandard checkStandard) {
        Long parentId = checkStandard.getParentId();
        if (parentId == null) {
            parentId = 0L;
        }
        String parentCode = "0";
        if(parentId != 0){
            parentCode = this.findById(parentId).getCode();
        }
        checkStandard.setParentId(parentId);
        String no = serialNumberService.getSerialNumber("en_checkStandard", parentCode);
        checkStandard.setCode(no);
        this.save(checkStandard);


        this.update(checkStandard);
        return checkStandard;
    }

    public CheckStandard updateCheckStandard(CheckStandard checkStandard){
        Long parentId = checkStandard.getParentId();
        if (parentId == null) {
            parentId = 0L;
        }
        if(parentId.longValue() == checkStandard.getId()){
            throw new BizException("不能作为自己的父级",false);
        }
        CheckStandard oldBean = this.findById(checkStandard.getId());
        Long oldParentId = oldBean.getParentId();
        BeanUtils.beanCopy(checkStandard,oldBean);
        if(oldParentId == parentId.longValue()){  //直接修改属性
            this.update(oldBean);
        }else{  //修改了父级，则涉及到的编码包括该级的下一级编码都得改
            String parentCode = "0";
            if(parentId != 0){
                parentCode = this.findById(parentId).getCode();
            }
            String no = serialNumberService.getSerialNumber("en_checkStandard", parentCode);
            oldBean.setCode(no);
            this.update(oldBean);

            //查询下一级修改
            updateChildrenForNo(oldBean.getId(),no);
        }
        return oldBean;
    }

    private void updateChildrenForNo(Long parentId,String parentNo){
        List<CheckStandard> childCheckStandardList = this.getChildrenByParentId(parentId);
        if(CollectionUtils.isNotEmpty(childCheckStandardList)){
            for (CheckStandard childCheckStandard : childCheckStandardList) {
                String childNo = serialNumberService.getSerialNumber("en_checkStandard", parentNo);
                childCheckStandard.setCode(childNo);
                this.save(childCheckStandard);

                updateChildrenForNo(childCheckStandard.getId(),childNo);

            }
        }
    }


}
